home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Everything For A Hacker
/
19990506-[HACK].iso
/
HEXEDIT
/
UTILS
/
80X0393.ARJ
/
TOADICE.ASM
< prev
next >
Wrap
Assembly Source File
|
1993-03-30
|
11KB
|
234 lines
;TOADICE Unscrambles a .COM file scrambled by ICE v1.0
; Usage: TOADICE program.com
; Warning: Overwrites the original "in situ", so be sure
; to have it saved somewhere in case there's a problem.
;
; Released to the public domain.
; Please do not distribute without documentation and source.
; David Kirschbaum
; Toad Hall
; Fayetteville NC (919) 868-3471
; kirsch@sesi.com
CR EQU 0DH
LF EQU 0AH
PROGCODE EQU 79H ;encrypted program code starting offset
;This structure replicates the beginning of an ICE'd program
icehdr STRUC
db ?,? ;EB,0A ;'JMP Start' ;100
wxor dw ? ;magic XOR word ;102
ptr127 dw ? ;0127H ;Ptr to 127H, just past loader ;104
;appears to be unused
proglen dw ? ;nr bytes in encrypted program ;106
decodlen dw ? ;nr bytes in encrypted decoder ;108
setup dw ? ;Address of runtime setup code ;10A
;(just beyond encrypted code)
Start dw ? ;BE 26 01 ;MOV SI,126H ;10C
ENDS
CSEG SEGMENT
ASSUME DS:CSEG, SS:CSEG ,CS:CSEG ,ES:CSEG
ORG 100H
ToadIce PROC FAR
handle label word ;Waste not, want not, eh?
call OpenFile ;open, set up to read target ICEd file
int 21H
jnb ReadOk ;all went ok
mov dx,offset readerr ;'File read error'
jmp MsgTerm ;(DOS'll close the open file)
logo db 'TOADICE: $'
readerr db 'File read error$'
createrr db 'File create error$'
writerr db 'File write error$'
noticed db 'File is not ICEd$'
okmsg db 'deICEd$'
ReadOk:
;BX = file handle
;DX = input buffer (b)
;SI = AsciiZ filename
mov ah,3EH ;close file
int 21H
;Check to see if the program was in fact ICE'd.
mov bx,dx ;b and header structure
cmp [bx],0AEBH ;EB 0A, JMP 010CH
jnz NoMatch ;nope, not ICEd
cmp [bx].ptr127,127H ;constant in header
jnz NoMatch ;nope
cmp [bx].Start,26BEH ;BE 26 01, MOV SI,126
jz Iced ;Enough already
NoMatch:
mov dx,offset noticed ;'Not iced'
mov al,0FFH ;ERRORLEVEL
jmp MsgTerm
Iced: ;Ok, so it's an ICEd .COM file.
;Now we "create" a file with the same name (saved in SI)
;just so we can write back out to it.
;(This is the only way to "truncate" it cleanly.)
mov dx,si ;AsciiZ file name from PSP cmdline
xor cx,cx ;normal file attributes
mov ah,3CH ;create a file
int 21H
jnb CreateOk
mov dx,offset createrr ;'Create error'
jmp MsgTerm ;AL=ERRORLEVEL
CreateOk:
mov handle,ax ;save file handle
mov si,offset b + 26H ;start decoding the mover/decoder,
;plus the encoded program
;(yes, we must do it all)
mov di,si ;put decoded words right back
mov cx,b.decodlen ;nr of words to decode
mov dx,b.wxor ;magic XOR value for decoding
cld ;insure fwd
DecodeLup:
lodsw
xor ax,dx ;decode
stosw ;put it back
mov dx,ax ;new XOR value
loop DecodeLup ;do the entire mover/decoder
;This portion (a tweaked copy of the original decoder) moves decoded but
;possibly compressed program code/data to the stack, and then copies it
;back (possibly decompressing it) to the same place.
;This is all very odd, because if it *had* been truly compressed,
;it should now overwrite ICE's setup code that lies beyond
;the compressed program code.
;Methinks they lie to us ... ICE'd programs will *always* be larger
;than the original, because that program area will *always* be as
;large as the original (uncompressed) program.
mov si,offset b + PROGCODE ;from start of encrypted code
push si ;save for DX (write to disk)
push si ;save for DI later (putback)
mov cx,b.proglen ;nr bytes to move
inc cx ;adjust
push cx ;save nr bytes
mov di,0FEFFH ;to temporary work area in stack
add si,cx ;plus length
dec si ;adjust start point
std ;backwards
repz movsb ;copy encrypted code to himem
mov si,di ;where we stopped
inc si ;from
pop cx ;same nr bytes
pop di ;b+PROGCODE: same place
cld ;forward
ExpandLup:
lodsb ;next encrypted byte
cmp cx,0 ;sign set (e.g., big value)
jl Chk_RLC ;yep, check for compression
cmp cx,2
jng Relup ;too close to end, no expansion
Chk_RLC:
cmp al,0D5H ;special flag for RLC (run-length
compression)
jz GotRlc ;yep, that's it
stosb ;regular char, stuff it
jmp short Relup
GotRlc: lodsw ;repeated char count (AH), char (AL)
dec cx ;adjust loop counter
dec cx ;by 2
push cx ;save it
xor ch,ch ;clear msb
mov cl,ah ;here's the repeat value
inc cx ;new count of bytes to stuff
repz stosb ;stuff x repeated chars
pop cx ;restore loop counter
Relup: loop ExpandLup
;Code is decrypted, uncompressed, etc.
pop dx ;b+PROGCODE: decoded program code start
mov cx,b.setup ;ICE's code beyond program code
sub cx,100H+PROGCODE ;minus where ICE thinks the program
code
;would start = program length
mov bx,handle ;output file handle
mov ah,40H ;write to file/device
int 21H
mov dx,offset writerr ;'Write fail'
jb MsgTerm ;error msg, return AL
mov ah,3EH ;close file, just to be neat
int 21H ;(although DOS would do it
;when we terminate)
mov dx,offset okmsg ;'deICEd'
xor ax,ax ;ERRORLEVEL 0
MsgTerm:
push ax ;save ERRORLEVEL
push dx ;save DX terminal msg a sec
mov dx,offset logo ;'TOADICE: '
mov ah,9 ;display msg
int 21H
pop dx ;original msg
MsgTerm2:
mov ah,9 ;display msg
int 21H
pop ax ;original ERRORLEVEL in AL
mov ah,4CH ;terminate process
int 21H
ToadIce ENDP
;This data and code will be overwritten when we read in
;the ICE'd program as data.
b label icehdr
usage db 'Usage: TOADICE progname.com',CR,LF
db "Unscrambles an ICE'd .COM program, overwriting the original."
db CR,LF
db 'Author: David Kirschbaum, Toad Hall, v1.0 Dec 92',CR,LF
db 'Donated to the Public Domain (with .ASM src, natch)'
db CR,LF,'$'
openerr db 'File open error$'
OpenFile PROC NEAR
cld
mov si,80H ;PSP cmdline
lodsb ;cmdline length
or al,al
jnz Spaces ; If 0, no command line
mov dx,offset usage ;'Usage: ...'
mov al,0FFH ;ERRORLEVEL
jmp short Die ;display, terminate
Spaces: lodsb
cmp al,20h ;Space?
jz Spaces ;Gobble leading spaces
dec si ;back up to first char
mov dx,si ;DX -> filename start
;Now we must Asciize the filename with a terminating 0
GetCr: lodsb
cmp al,CR ;Terminating CR?
jnz GetCr ;nope, loop
dec si
mov byte ptr [si],0 ;Asciize the filename
mov si,dx ;remember filename start in SI
mov ax,3D00H ;open file for read only
int 21H
jnb OpenOk ;fine
mov dx,offset openerr ;'File open error'
Die: push ax ;for upcoming POP
jmp MsgTerm2 ;ERRLEVEL in AL
OpenOk: mov bx,ax ;file handle into BX
mov cx,0FE00H ;max read (leaving room for stack)
mov dx,offset b ;our buffer
sub cx,dx ;CX = max available space
mov ah,3FH ;read from file/device
ret ;we'll read after the return
;since it'll overwrite this code
OpenFile ENDP
CSEG ENDS
END ToadIce